package com.study.zk;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

/**
 * 1.获取zk客户端连接对象
 * 2.调用相关API完成相应功能
 * 3.关闭资源
 */
public class ZookeeperTest {
    private ZooKeeper zk;

    /**
     * 测试递归删除
     */
    @Test
    public void testDeleteAll() throws KeeperException, InterruptedException {
        deleteAll("/a",zk);
    }

    /**
     * 递归删除节点
     * @throws KeeperException
     * @throws InterruptedException
     */
    public void deleteAll(String path,ZooKeeper zk) throws KeeperException, InterruptedException{
        //判断当前结点是否存在
        Stat stat = zk.exists(path, false);
        if ((stat==null)){
            System.out.println("不存在");
        }else {
            //递归删除节点
            //获取当前结点的子节点
            List<String> children = zk.getChildren(path, false);
            if ((children.isEmpty())){
                //没有子节点，直接删除
                zk.delete(path,stat.getVersion());
            }else {
                //递归调用自己删除所有子节点
                for (String child : children) {
                    deleteAll(path+"/"+child,zk);
                }
                //删除自己
                deleteAll(path,zk);
            }
        }

    }

    /**
     * 删除节点
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void testDelete() throws KeeperException, InterruptedException{
        //封装path
        String path="/sanguo";
        //判断当前结点是否存在
        Stat stat = zk.exists(path, false);
        if ((stat==null)){
            System.out.println("不存在");
        }else {
            //删除节点
            zk.delete(path,stat.getVersion());
        }

    }


    /**
     * 修改结点下内容
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void testSetData() throws KeeperException, InterruptedException{
        //封装path
        String path="/sanguo";
        //判断当前结点是否存在
        Stat stat = zk.exists(path, false);
        if ((stat==null)){
            System.out.println("不存在");
        }else {
            zk.setData(path,"guanyu,zhanggei,liubei".getBytes(),stat.getVersion());
        }

    }

    /**
     * 获取当前结点数据
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void testGetData() throws KeeperException, InterruptedException{
        //封装path
        String path="/sanguo";
        //判断当前结点是否存在
        Stat stat = zk.exists(path, false);
        if ((stat==null)){
            System.out.println("不存在");
        }else {
            byte[] datas = zk.getData(path, false, stat);
            System.out.println(new String(datas));
        }

    }


    /**
     * 判断结点是否为空
     */
    @Test
    public void testExist() throws KeeperException, InterruptedException{
        Stat stat = zk.exists("/sanguo", false);
        if ((stat==null)){
            System.out.println("不存在");
        }else {
            System.out.println("存在");
        }
    }

    /**
     * 获取子节点
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void testgetChildren() throws KeeperException, InterruptedException {
        //获取子节点（不监控）
//        List<String> children = zk.getChildren("/", false);
        List<String> children = zk.getChildren("/", new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                System.out.println("此目录下结点有变化。。。");
            }
        });
        for (String child : children) {
            System.out.println(child);
        }
        Thread.sleep(Long.MAX_VALUE);
    }

    /**
     * 创建结点
     * 1.String path：指定创建结点的路径
     * 2.byte[] data：创建结点下的内容
     * 3.List<ACL> acl：对操作用户的权限控制
     * 4.CreateMode createMode：指定当前结点类型（持久化的 临时的）
     */
    @Test
    public void testCreate() throws KeeperException, InterruptedException {
       zk.create("/sanguo",
               "guanyu".getBytes(),
               ZooDefs.Ids.OPEN_ACL_UNSAFE,
               CreateMode.CONTAINER);
    }


    /**
     * 获取连接对象
     * @throws IOException
     */
    @Before
    public void init() throws IOException {
        String connerString="hadoop102:2181,hadoop103:2181,hadoop104:2181";
        int sessionTimeout=10000;
        zk = new ZooKeeper(connerString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {

            }
        });
    }

    /**
     * 关闭连接
     * @throws InterruptedException
     */
    @After
    public void close() throws InterruptedException {
        zk.close();
    }

    /**
     * 1.connectString：连接zk服务的地址：hadoop102:2181,hadoop103:2181,hadoop104:2181
     * 2.sessionTimeout:超时时间
     */
    @Test
    public void testCreateZookeeperClient() throws IOException, InterruptedException {
        String connerString="hadoop102:2181,hadoop103:2181,hadoop104:2181";
        int sessionTimeout=10000;
            ZooKeeper zooKeeper = new ZooKeeper(connerString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                System.out.println("根据具体业务进行下一步操作！！！");
            }
        });

        System.out.println("zk:*********"+zooKeeper);
        zooKeeper.close();
    }
}
